
; ------------------------------------------------------------------
; Disk description table, to make it a valid mbr
; Note: some of these values are hard-coded in the source!
	  org 0600h
_start: 	cli
		xor ax,ax
		mov ds,ax
		mov es,ax
		mov ss,ax
		mov sp,7C00h
		sti
		cld
		mov si,sp		; Start address
		mov di,0600h		; Destination address
		mov cx,512/2
		rep movsw
   DriveNo	   equ 0800h
;
; Now, jump to the copy at 0600h so we can load the boot sector at 7C00h.
; Since some BIOSes seem to think 0000:7C00h and 07C0:0000h are the same
; thing, use a far jump to canonicalize the address.  This also makes
; sure that it is a code speculation barrier.
;

		jmp 0:next		; Jump to copy at 0600h
				
next:
		mov [DriveNo], dl		; Drive number stored in DL
		 mov si,missing_os_msg
		jmp die

;
; Check for CHS parameters.  This doesn't work on floppy disks,
; but for an MBR we don't care.
;
		mov ah,08h			; Get drive parameters
		int 13h
		xor ax,ax
		mov al,dh
		inc ax				; From 0-based to count
		mov [Heads],ax
		and cl,3Fh			; Max sector number
		mov [Sectors],cl
		; Note: we actually don't care about the number of
		; cylinders, since that's the highest-order division

	     ;
; Now look for one (and only one) active partition.
;
		mov si,PartitionTable
		xor ax,ax
		mov cx,4
checkpartloop:
		test byte [si],80h
		jz .notactive
		inc ax
		mov di,si
.notactive:	add si,16
		loop checkpartloop

		cmp ax, 1		    ; Better be only one
		jnz not_one_partition

;
; Now we have the active partition partition information in DS:DI.
; Check to see if we support EBIOS.
;
		mov dl,[DriveNo]
		mov ax,4100h
		mov bx,055AAh
		xor cx,cx
		xor dh,dh
		stc
		int 13h
		jc no_ebios
		cmp bx,0AA55h
		jne no_ebios
		test cl,1			; LBA device access
		jz no_ebios
;
; We have EBIOS.  Load the boot sector using LBA.
;
		push di
		mov si,dapa
		mov bx,[di+8]			; Copy the block address
		mov [si+8],bx
		mov bx,[di+10]
		mov [si+10],bx
		mov dl,[DriveNo]
		mov ah,42h			; Extended Read
		jmp short common_tail
;
; No EBIOS.  Load the boot sector using CHS.
;
no_ebios:
		push di
		mov ax,[di+8]
		mov dx,[di+10]
		div word [Sectors]
		inc dx
		mov cx,dx			; Sector #
		xor dx,dx
		div word [Heads]
		; DX = head #, AX = cylinder #
		mov ch,al
		shr ax,1
		shr ax,1
		and al,0C0h
		or cl,al
		mov dh,dl			; Head #
		mov dl,[DriveNo]
		mov bx,7C00h
		mov ax,0201h			; Read one sector
common_tail:
		int 13h
		jc disk_error
		pop si				; DS:SI -> partition table entry
;
; Verify that we have a boot sector, jump
;
		cmp word [7C00h+510],0AA55h
		jne missing_os
		cli
		jmp 0:7C00h			; Jump to boot sector; far
						; jump is speculation barrier
						; (Probably not neecessary, but
						; there is plenty of space.)

not_one_partition:
		ja too_many_os
missing_os:
		mov si,missing_os_msg
		jmp short die
too_many_os:
disk_error:
		mov si,bad_disk_msg
die:
.msgloop:
		lodsb
		xor al,al
		jz .now
		mov ah,0Eh			; TTY output
		mov bx,0007h
		int 10h
		jmp short .msgloop
.now:
		jmp short .now

;;                align 4, db 0                   ; Begin data area

;
; EBIOS disk address packet
;
dapa:
		dw 16				; Packet size
.count: 	dw 1				; Block count
.off:		dw 7C00h			; Offset of buffer
.seg:		dw 0				; Segment of buffer
.lba:		dd 0				; LBA (LSW)
		dd 0				; LBA (MSW)


; CHS information
Heads:		dw 0
Sectors:	dw 0
DriveNo 	equ 0800h
; Error messages
missing_os_msg	db 'Missing operating system', 13, 10, 0
bad_disk_msg	db 'Operating system loading error', 13, 10, 0

;
; Maximum MBR size: 446 bytes; end-of-boot-sector signature also needed.
; Note that some operating systems (NT, DR-DOS) put additional stuff at
; the end of the MBR, so shorter is better.
;

times 446-($-$$) db 0	; Pad remainder of boot sector with zeros
;Partition Table
PartitionTable:
OEMLabel		db 80h	 ; Disk label
CHS1		    db 00h   ; Disk label
CHS2		    db 02h   ; Disk label
CHS3		    db 00h   ; Disk label
TYPE		    db 1ah   ; Unkown
CHSe1		     db 00h   ; Disk label
CHSe2		     db 3Fh   ; Disk label
CHSe3		     db 00h   ; Disk label
SS1		      db 01h;
SS2		      db 00h;
SS3		      db 00h;
SS4		      db 00h;
SaS1		       db 3Eh;
SaS2		       db 00h;
SaS3		       db 00h;
SaS4		       db 00h;

; END OF BOOT SECTOR AND BUFFER START

	times 510-($-$$) db 0	; Pad remainder of boot sector with zeros
	dw 0AA55h		; Boot signature (DO NOT CHANGE!)

; kernel
  mov si,missing_os_msg2
		jmp die2
    die2:
.msgloop2:
		lodsb
		xor al,al
		jz .now2
		mov ah,0Eh			; TTY output
		mov bx,0007h
		int 10h
		jmp short .msgloop2
.now2:
		jmp short .now2

missing_os_msg2  db 'Missing operating system', 13, 10, 0
; END OF BOOT SECTOR AND BUFFER START

	times 1022-($-$$) db 0	 ; Pad remainder of boot sector with zeros
	dw 0AA55h		; Boot signature (DO NOT CHANGE!)
 times 32256-($-$$) db 0   ; Pad remainder of boot sector with zeros